use clap::{Parser, Subcommand};

mod commands;
mod utils;

#[derive(Parser)]
#[command(
    name = "frontend-toolkit",
    about = "🚀 All-in-one CLI toolkit for frontend developers",
    version,
    author
)]
struct Cli {
    #[command(subcommand)]
    command: Commands,
}

#[derive(Subcommand)]
enum Commands {
    /// Minify CSS/JS files
    Minify {
        /// Input file path
        #[arg(short, long)]
        input: String,
        /// Output file path (optional)
        #[arg(short, long)]
        output: Option<String>,
        /// File type (css/js)
        #[arg(short, long, default_value = "css")]
        r#type: String,
    },
    /// Convert JSON to TypeScript interfaces
    Json2ts {
        /// Input JSON file
        #[arg(short, long)]
        input: String,
        /// Interface name
        #[arg(short, long, default_value = "ApiResponse")]
        name: String,
        /// Output file (optional)
        #[arg(short, long)]
        output: Option<String>,
    },
    /// Generate component templates
    Component {
        /// Component name
        name: String,
        /// Framework (react/vue)
        #[arg(short, long, default_value = "react")]
        framework: String,
        /// Output directory
        #[arg(short, long, default_value = "./")]
        output: String,
    },
    /// Analyze package.json dependencies
    Deps {
        /// package.json path
        #[arg(short, long, default_value = "./package.json")]
        path: String,
    },
    /// Start static file server
    Serve {
        /// Directory to serve
        #[arg(short, long, default_value = "./")]
        dir: String,
        /// Port number
        #[arg(short, long, default_value = "3000")]
        port: u16,
        /// Enable hot reload
        #[arg(long, action = clap::ArgAction::SetTrue)]
        hot: bool,
    },
    /// Create Vue3 full-stack project
    CreateVue3 {
        /// Project name
        name: String,
        /// Project template (basic/router/pinia/full)
        #[arg(short, long, default_value = "full")]
        template: String,
        /// Use TypeScript
        #[arg(long, action = clap::ArgAction::SetTrue)]
        typescript: bool,
        /// Output directory
        #[arg(short, long, default_value = "./")]
        output: String,
    },
    /// Create React project with full ecosystem
    CreateReact {
        /// Project name
        name: String,
        /// Project template (basic/router/zustand/full)
        #[arg(short, long, default_value = "full")]
        template: String,
        /// Use TypeScript
        #[arg(long, action = clap::ArgAction::SetTrue)]
        typescript: bool,
        /// Output directory
        #[arg(short, long, default_value = "./")]
        output: String,
    },
    /// Generate changelog from git commits
    Changelog {
        /// Generate changelog with specific tag
        #[arg(short, long)]
        tag: Option<String>,
        /// Preview unreleased changes only
        #[arg(long, action = clap::ArgAction::SetTrue)]
        preview: bool,
    },
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let cli = Cli::parse();

    match cli.command {
        Commands::Minify {
            input,
            output,
            r#type,
        } => {
            commands::minify::run(input, output, r#type).await?;
        }
        Commands::Json2ts {
            input,
            name,
            output,
        } => {
            commands::json2ts::run(input, name, output).await?;
        }
        Commands::Component {
            name,
            framework,
            output,
        } => {
            commands::component::run(name, framework, output).await?;
        }
        Commands::Deps { path } => {
            commands::deps::run(path).await?;
        }
        Commands::Serve { dir, port, hot } => {
            commands::serve::run(dir, port, hot).await?;
        }
        Commands::CreateVue3 {
            name,
            template,
            typescript,
            output,
        } => {
            commands::create_vue3::run(name, template, typescript, output).await?;
        }
        Commands::CreateReact {
            name,
            template,
            typescript,
            output,
        } => {
            commands::create_react::run(name, template, typescript, output).await?;
        }
        Commands::Changelog { tag, preview } => {
            if preview {
                commands::changelog::run_preview()?;
            } else if let Some(tag_name) = tag {
                commands::changelog::run_with_tag(&tag_name)?;
            } else {
                commands::changelog::run()?;
            }
        }
    }

    Ok(())
}
